import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;


public class Calculator {
	public static final double resolution = 0.1;
	
	Calculator(){
	}
	
	/**
	 * we assume both fuzzynumbers have the same resolution
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public FuzzyNumber addFN(FuzzyNumber num1, FuzzyNumber num2) throws Exception{
		HashMap<Double,GeneralSegment> newnum = new HashMap<Double,GeneralSegment>();
		int size = Math.max(num1.getAlphacuts().size(), num2.getAlphacuts().size());
		Iterator<Entry<Double,GeneralSegment>> it1 = num1.getAlphacuts().entrySet().iterator();
		Iterator<Entry<Double,GeneralSegment>> it2 = num2.getAlphacuts().entrySet().iterator();
		
		Entry<Double,GeneralSegment> entry1;
		Entry<Double,GeneralSegment> entry2;
		GeneralSegment newseg;
		double currentalpha = 0;
		for (int i=0; i<size; i++){
			if (it1.hasNext()){
				entry1 = it1.next();
				currentalpha = entry1.getKey();
			}else {entry1 = null;}
			if (it2.hasNext()){
				entry2 = it2.next();
				currentalpha = entry2.getKey();
			}else {entry2 = null;}
			
			if (entry1 == null && entry2 == null){
				throw new Exception("At least one of the Fuzzy Numbers has an empty alphacut");
			}
			else if (entry1 == null){
				newseg = entry2.getValue().addition(new GeneralSegment());
			}
			else if (entry2 == null){
				newseg = entry1.getValue().addition(new GeneralSegment());
			}
			else{
				newseg = entry1.getValue().addition(entry2.getValue());
			}
			newnum.put(currentalpha, newseg);
		}
		return new FuzzyNumber(newnum);
	}
	
	public FuzzyNumber substractFN(FuzzyNumber num1, FuzzyNumber num2) throws Exception{
		HashMap<Double,GeneralSegment> newnum = new HashMap<Double,GeneralSegment>();
		int size = Math.max(num1.getAlphacuts().size(), num2.getAlphacuts().size());
		Iterator<Entry<Double,GeneralSegment>> it1 = num1.getAlphacuts().entrySet().iterator();
		Iterator<Entry<Double,GeneralSegment>> it2 = num2.getAlphacuts().entrySet().iterator();
		
		Entry<Double,GeneralSegment> entry1;
		Entry<Double,GeneralSegment> entry2;
		GeneralSegment newseg;
		double currentalpha = 0;
		for (int i=0; i<size; i++){
			if (it1.hasNext()){
				entry1 = it1.next();
				currentalpha = entry1.getKey();
			}else {entry1 = null;}
			if (it2.hasNext()){
				entry2 = it2.next();
				currentalpha = entry2.getKey();
			}else {entry2 = null;}
			
			if (entry1 == null && entry2 == null){
				throw new Exception("At least one of the Fuzzy Numbers has an empty alphacut");
			}
			else if (entry1 == null){
				newseg = entry2.getValue().substraction(new GeneralSegment());
			}
			else if (entry2 == null){
				newseg = entry1.getValue().substraction(new GeneralSegment());
			}
			else{
				newseg = entry1.getValue().substraction(entry2.getValue());
			}
			newnum.put(currentalpha, newseg);
		}
		return new FuzzyNumber(newnum);
	}
	
	public FuzzyNumber multiplyFN(FuzzyNumber num1, FuzzyNumber num2) throws Exception{
		HashMap<Double,GeneralSegment> newnum = new HashMap<Double,GeneralSegment>();
		int size = Math.max(num1.getAlphacuts().size(), num2.getAlphacuts().size());
		Iterator<Entry<Double,GeneralSegment>> it1 = num1.getAlphacuts().entrySet().iterator();
		Iterator<Entry<Double,GeneralSegment>> it2 = num2.getAlphacuts().entrySet().iterator();
		
		Entry<Double,GeneralSegment> entry1;
		Entry<Double,GeneralSegment> entry2;
		GeneralSegment newseg;
		double currentalpha = 0;
		for (int i=0; i<size; i++){
			if (it1.hasNext()){
				entry1 = it1.next();
				currentalpha = entry1.getKey();
			}else {entry1 = null;}
			if (it2.hasNext()){
				entry2 = it2.next();
				currentalpha = entry2.getKey();
			}else {entry2 = null;}
			
			if (entry1 == null && entry2 == null){
				throw new Exception("At least one of the Fuzzy Numbers has an empty alphacut");
			}
			else if (entry1 == null){
				newseg = entry2.getValue().multiply(new GeneralSegment());
			}
			else if (entry2 == null){
				newseg = entry1.getValue().multiply(new GeneralSegment());
			}
			else{
				newseg = entry1.getValue().multiply(entry2.getValue());
			}
			newnum.put(currentalpha, newseg);
		}
		return new FuzzyNumber(newnum);
	}
	
	public FuzzyNumber divideFN(FuzzyNumber num1, FuzzyNumber num2) throws Exception{
		HashMap<Double,GeneralSegment> newnum = new HashMap<Double,GeneralSegment>();
		int size = Math.max(num1.getAlphacuts().size(), num2.getAlphacuts().size());
		Iterator<Entry<Double,GeneralSegment>> it1 = num1.getAlphacuts().entrySet().iterator();
		Iterator<Entry<Double,GeneralSegment>> it2 = num2.getAlphacuts().entrySet().iterator();
		
		Entry<Double,GeneralSegment> entry1;
		Entry<Double,GeneralSegment> entry2;
		GeneralSegment newseg;
		double currentalpha = 0;
		for (int i=0; i<size; i++){
			if (it1.hasNext()){
				entry1 = it1.next();
				currentalpha = entry1.getKey();
			}else {entry1 = null;}
			if (it2.hasNext()){
				entry2 = it2.next();
				currentalpha = entry2.getKey();
			}else {entry2 = null;}
			
			if (entry1 == null && entry2 == null){
				throw new Exception("At least one of the Fuzzy Numbers has an empty alphacut");
			}
			else if (entry1 == null){
				newseg = entry2.getValue().divide(new GeneralSegment());
			}
			else if (entry2 == null){
				newseg = entry1.getValue().divide(new GeneralSegment());
			}
			else{
				newseg = entry1.getValue().divide(entry2.getValue());
			}
			newnum.put(currentalpha, newseg);
		}
		return new FuzzyNumber(newnum);
	}
}
